/**
 * 
 */
package com.monkeyboy.security.config.mobile;

import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.InternalAuthenticationServiceException;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;

/**
 * @Description
 *
 * @author Gavin<br>
 *         2019年8月27日
 */
public class SmsCodeAuthenticationProvider implements AuthenticationProvider {
	private UserDetailsService userDetailsService;

	public UserDetailsService getUserDetailsService() {
		return userDetailsService;
	}

	public void setUserDetailsService(UserDetailsService userDetailsService) {
		this.userDetailsService = userDetailsService;
	}

	/**
	 * 进行身份认证的逻辑
	 */
	@Override
	public Authentication authenticate(Authentication authentication) throws AuthenticationException {
		SmsCodeAuthenticationToken authenticationToken = (SmsCodeAuthenticationToken) authentication;
		UserDetails user = userDetailsService.loadUserByUsername((String) authenticationToken.getPrincipal());
		if (user == null) {
			throw new InternalAuthenticationServiceException("无法获取用户信息");
		}
		/**
		 * 注意上面的步骤海没有进行数据库的认证逻辑操作，需要在这里进行真正的逻辑操作然后返回认证通过的authentication<br>
		 * note:
		 * SmsCodeAuthenticationToken中的单参数构造器是构建的一个未通过认证的用户信息，下面多个参数的才是构建成功的授权通过的信息，可查看源代码
		 */
		// 上面认证成功后重新构建认证成功的用户信息
		SmsCodeAuthenticationToken authenticationResult = new SmsCodeAuthenticationToken(user, user.getAuthorities());
		authenticationResult.setDetails(authenticationToken.getDetails());// 之前未认证的detail信息设置到这个新的token认证信息里面
		return authenticationResult;
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * org.springframework.security.authentication.AuthenticationProvider#supports(
	 * java.lang.Class)
	 */
	@Override
	public boolean supports(Class<?> authentication) {
		// TODO Auto-generated method stub
		return SmsCodeAuthenticationToken.class.isAssignableFrom(authentication);
	}

}
